enum NodeType { STR, ID, INT, KEYWORD, BOOL, YSTAR, TAU, COMMA,
                LAMBDA, EQUALS, DUMMY, NIL, NEG, NOT, OR, 
                AND, GR, GE, LS, LE, EQ, NE, PLUS, MINUS,
                MULTI, DIVIDE, EXPO, AUG, CONDITIONAL, GAMMA
    }
public class TreeNode extends ControlBase {
    private boolean isTerminal = false;
    private NodeType type;
    private Token t;
    private TreeNode extraNode;
    private TreeNode leftChild;
    private TreeNode rightChild;
    public String name;
    public String stringValue;
    public boolean boolValue;
    public int intValue;
    int location;
    
    public TreeNode() {
        extraNode = leftChild = rightChild = null;
    }
    
        
    public TreeNode(TreeNode parent, TreeNode left, TreeNode right) {
        this.extraNode = parent;
        this.leftChild = left;
        this.rightChild = right;
    }
    
    public TreeNode(String s) {
        extraNode = leftChild = rightChild = null;
        this.name = s;
    }
    
    public TreeNode (NodeType type, String value) {
        this.type = type;
        this.stringValue = value;
        switch(type) {
        case INT:
            try {
                intValue = Integer.parseInt(value);
            }catch(NumberFormatException e){
                e.printStackTrace();
            }
            break;
        case BOOL:
            boolValue = Boolean.parseBoolean(value);
            break;
        case ID:
            name = value;
        case STR:
            name = value;
        default:
            break;
        }
    }
    
    public void setExtraChild(TreeNode node){
        this.extraNode = node;
    }
    
    public TreeNode getExtraChild() {
        return this.extraNode;
    }
    
    public void setLeftChild(TreeNode node){
        this.leftChild = node;
    }
    
    public TreeNode getLeftChild() {
        return this.leftChild;
    }
    public void setRightChild(TreeNode node){
        this.rightChild = node;
    }
    
    public TreeNode getRightChild() {
        return this.rightChild;
    }
    
    public void setType(NodeType type) {
        this.type = type;
    }
    
    public NodeType getType() {
        return this.type;
    }
    
    public Token getToken() {
        return this.t;
    }
    
    public void setToken(Token t) 
    {
        this.t = t;
    }
    
    public TreeNode clone() {
        TreeNode n = new TreeNode(this.name);
        n.type = this.type;
        n.stringValue = this.stringValue;
        return n;
    }
    
    public void copy(TreeNode origi)
    {
        this.name = origi.name;
        this.stringValue = origi.stringValue;
        this.intValue = origi.intValue;
        this.type = origi.type;
        this.leftChild = origi.leftChild;
        this.rightChild = origi.rightChild;
        this.extraNode = origi.extraNode;
    }
    
    public void setName(String s) {
        this.name = s;
    }
    
    public void terminal() {
        isTerminal = true;
        leftChild = null;
        rightChild = null;
        isTerminal = true;
    }
    
    public String toString() {
        return name;
    }
    
    public boolean isTerminal() {
        return this.isTerminal;
    }
}
